package com.hsurosy.hsuchain.nft.notice.domain.service;

import com.hsurosy.hsuchain.nft.base.exception.BizException;
import com.hsurosy.hsuchain.nft.notice.domain.constant.NoticeState;
import com.hsurosy.hsuchain.nft.notice.domain.constant.NoticeType;
import com.hsurosy.hsuchain.nft.notice.domain.entity.Notice;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hsurosy.hsuchain.nft.notice.infrastruture.mapper.NoticeMapper;
import org.springframework.stereotype.Service;

import static com.hsurosy.hsuchain.nft.base.exception.BizErrorCode.NOTICE_SAVE_FAILED;

/**
 * 通知服务
 *
 * @Author Hsu琛君珩
 * @Date 2024-10-05 16:55
 * @Description
 * @Version: v1.0.0
 */
@Service
public class NoticeService extends ServiceImpl<NoticeMapper, Notice> {

    /**
     * 短信通知标题，常用于验证码发送
     */
    private static final String SMS_NOTICE_TITLE = "验证码";

    /**
     * 分页查询需要重试的通知（INIT或FAILED状态）
     *
     * @param currentPage 当前页
     * @param pageSize 每页大小
     * @return 包含通知信息的分页结果
     */
    public Page<Notice> pageQueryForRetry(int currentPage, int pageSize) {
        // 创建分页对象
        Page<Notice> page = new Page<>(currentPage, pageSize);

        // 构建查询条件
        QueryWrapper<Notice> wrapper = new QueryWrapper<>();
        wrapper.in("state", NoticeState.INIT.name(), NoticeState.FAILED);
        wrapper.orderBy(true, true, "gmt_create");

        // 执行分页查询并返回结果
        return this.page(page, wrapper);
    }

    /**
     * 保存短信验证码通知
     *
     * @param telephone 接收短信的电话号码
     * @param captcha 验证码内容
     * @return 保存的通知对象
     * @throws BizException 当保存通知失败时抛出业务异常
     */
    public Notice saveCaptcha(String telephone, String captcha) {
        // 构建通知对象
        Notice notice = Notice.builder()
                .noticeTitle(SMS_NOTICE_TITLE)
                .noticeContent(captcha)
                .noticeType(NoticeType.SMS)
                .targetAddress(telephone)
                .state(NoticeState.INIT)
                .build();

        // 保存通知
        Boolean saveResult = this.save(notice);

        // 检查保存结果，如果失败则抛出业务异常
        if (!saveResult) {
            throw new BizException(NOTICE_SAVE_FAILED);
        }

        return notice;
    }
}
